#include "sobjc-commons/str_stream.h"
#include "sobjc-commons/defines.h"
#include "sobjc-commons/utils.h"

#define DEFAULT_SIZE    20

struct _objc_str_stream {
  char *s;
  size_t size;
  size_t s_size;
};

objc_str_stream_t
objc_make_str_stream()
{
  objc_str_stream_t st;

  st = ALLOC(struct _objc_str_stream);
  st->s = ALLOC_N(char, DEFAULT_SIZE);
  st->s[0] = 0;
  st->size = DEFAULT_SIZE;
  st->s_size = 0;

  return st;
}

void
objc_free_str_stream(objc_str_stream_t self)
{
  objc_free(self->s);
  objc_free(self);
}

char *
objc_str_stream_value(objc_str_stream_t self)
{
  return self->s;
}

char *
objc_str_stream_copy_value(objc_str_stream_t self)
{
  return objc_strdup(self->s);
}

char *
objc_str_stream_copy_value_and_free(objc_str_stream_t self)
{
  char *s;

  s = objc_str_stream_copy_value(self);
  objc_free_str_stream(self);

  return s;
}

void
objc_str_stream_write(objc_str_stream_t self, const char *s)
{
  size_t len;
  size_t old;

  old = self->s_size;
  len = strlen(s);
  if (self->size <= self->s_size + len) {
    self->size = (self->size + len) * 2;
    REALLOC_N(self->s, char, self->size);
  }
  strcpy(self->s + self->s_size, s);
  self->s_size += len;
}

void
objc_str_stream_writec(objc_str_stream_t self, const char c)
{
  char s[] = {0, 0};
  s[0] = c;
  objc_str_stream_write(self, s);
}

